package edu.utd.text.game.designer.controller;

import edu.utd.text.game.controller.commands.GameCommand;
import edu.utd.text.game.controller.parsing.AbstractParser;
import edu.utd.text.game.designer.exceptions.ExitRequestException;
import edu.utd.text.game.designer.parsers.DesignerParser;
import edu.utd.text.game.domain.GameMap;
import edu.utd.text.game.domain.areas.Room;
import edu.utd.text.game.domain.exceptions.DuplicateRoomException;
import edu.utd.text.game.domain.exceptions.UserInputParseException;

public class DesignerController {

	public final static DesignerController INSTANCE = new DesignerController();
	
	private DesignerController() { 
		init();
	}
	  //////////////////
	 //INSTANCE VARS //
	//////////////////
	
	private GameMap gameMap;
	private AbstractParser parser;
	
	public void init() {
		parser = DesignerParser.INSTANCE;
		gameMap = new GameMap();
	}

	  ////////////////////////
	 // COMMAND PROCESSING //
	////////////////////////

	public GameCommand parseUserInput(String userInput) 
			throws 	UserInputParseException, 
					ExitRequestException
	{
		try {
			return parser.parseInput(userInput);
		} catch (Exception e) {
			if (e instanceof UserInputParseException) {
				throw (UserInputParseException)e;
			}
			if (e instanceof ExitRequestException) {
				throw (ExitRequestException)e;
			}
			this.handleException(e);
		}
		return null;
	}
	
	public String doCommand(GameCommand aCommand) throws ExitRequestException {
		
		try {
			return aCommand.execute();
		} catch (Exception e) {
			if (e instanceof ExitRequestException) {
				throw (ExitRequestException)e;
			} else {
				e.printStackTrace();
				return "Hmm...there was an unexpected error doing that command...\n";
				
			}
		}
	}
	
	public void addRoom(Room room) throws DuplicateRoomException	{
		gameMap.addRoom(room);
	}
	
	  ////////////////////////
	 // EXCEPTION HANDLING //
	////////////////////////
	
	public void handleException(Exception e) {
		e.printStackTrace();
	}

	  //////////////////////
	 // GETTERS, SETTERS //
	//////////////////////
	
	public GameMap getGameMap() {
		return this.gameMap;
	}
	
	public void setGameMap(GameMap map) {
		this.gameMap = map;
	}
}
